package com.shop.common.handler;

import com.shop.common.enums.ExceptionEnum;
import com.shop.common.exception.OperationException;
import com.shop.common.response.ExceptionResponse;

import feign.RetryableException;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.UnsupportedJwtException;
import io.jsonwebtoken.security.SignatureException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;

import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.NoHandlerFoundException;

import java.net.UnknownHostException;
import java.util.Objects;

@Component
@ResponseBody
@ControllerAdvice
public class GlobalExceptionHandler {
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    // 处理自定义异常（最常用，放在最前面）
    @ExceptionHandler(OperationException.class)
    public ResponseEntity<ExceptionResponse> handleCustomException(OperationException ex) {
        // 日志分级：业务异常一般为WARN级别，避免淹没真正的错误日志
        //log.warn("Custom exception occurred: [code={}, message={}]", ex.getCode(), ex.getMessage());
          log.info("OperationException={}", ex.getMessage());
        ExceptionResponse response = new ExceptionResponse(
                ex.getCode(),
                ex.getMessage(),
                ex.getData()
        );

        // 使用自定义异常中可能包含的HTTP状态码，或通过业务码映射
//        HttpStatus status = Objects.nonNull(ex.getHttpStatus())
//                ? ex.getHttpStatus()
//                : getHttpStatusByCode(ex.getCode());
        HttpStatus status = HttpStatus.ACCEPTED;
        return new ResponseEntity<>(response, status);
    }
    //请求格式问题
    @ExceptionHandler({HttpMessageNotReadableException.class, HttpMediaTypeNotSupportedException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity<ExceptionResponse> handleHttpMessageNotReadableException() {
        ExceptionEnum exceptionEnum = ExceptionEnum.REQUEST_FORMAT;
        ExceptionResponse response = new ExceptionResponse(
                exceptionEnum
        );
        HttpStatus status = HttpStatus.BAD_REQUEST;
        return new ResponseEntity<>(response, status);
    }
    // 处理用户名不存在异常
    @ExceptionHandler(UsernameNotFoundException.class)
    public ResponseEntity<ExceptionResponse> handleUsernameNotFound(UsernameNotFoundException ex) {

        ExceptionEnum exceptionEnum = ExceptionEnum.USER_NOT_FOUND;
        ExceptionResponse response = new ExceptionResponse(
                exceptionEnum.getCode(),
                exceptionEnum.getMsg(),
                ex.getMessage()
        );
        return new ResponseEntity<>(response, HttpStatus.NOT_FOUND);
    }
    // 处理用户名不存在异常
    @ExceptionHandler(NoHandlerFoundException.class)
    public ResponseEntity<ExceptionResponse> NoHandlerFoundException(NoHandlerFoundException ex) {

        ExceptionEnum exceptionEnum = ExceptionEnum.NOT_FOUND;
        ExceptionResponse response = new ExceptionResponse(
                exceptionEnum.getCode(),
                exceptionEnum.getMsg(),
                ex.getMessage()
        );
        return new ResponseEntity<>(response, HttpStatus.NOT_FOUND);
    }
    // 处理密码错误异常
    @ExceptionHandler(BadCredentialsException.class)
    public ResponseEntity<ExceptionResponse> handleBadCredentials(BadCredentialsException ex) {
//        log.error("用户或者密码错误: {}", ex.getMessage());
        ExceptionEnum exceptionEnum = ExceptionEnum.LOGIN_FAILED;
        ExceptionResponse response = new ExceptionResponse(
                exceptionEnum.getCode(),
                exceptionEnum.getMsg()
        );
        return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
    }

    // 处理请求参数校验异常
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ExceptionResponse> handleValidationExceptions(MethodArgumentNotValidException ex) {
      //  Map<String, String> errors = new HashMap<>();
        //循环多个错误内容
//        ex.getBindingResult().getAllErrors().forEach(error -> {
//            String fieldName = ((FieldError) error).getField();
//            String errorMessage = error.getDefaultMessage();
//            errors.put(fieldName, errorMessage);
//        });
        ExceptionEnum exceptionEnum = ExceptionEnum.DATA_VALIDATION_FAILED;
        ExceptionResponse response = new ExceptionResponse(
                exceptionEnum.getCode(),
                Objects.requireNonNull(ex.getFieldError()).getDefaultMessage()
        );
        return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
    }
//
    // 处理JWT相关异常
    @ExceptionHandler(ExpiredJwtException.class)
    public ResponseEntity<ExceptionResponse> handleJwtExpired(ExpiredJwtException ex) {

        ExceptionEnum exceptionEnum = ExceptionEnum.EXPIRED_TOKEN;
        ExceptionResponse response = new ExceptionResponse(
                exceptionEnum.getCode(),
                exceptionEnum.getMsg()
        );
        return new ResponseEntity<>(response, HttpStatus.UNAUTHORIZED);
    }
    @ExceptionHandler({MalformedJwtException.class, SignatureException.class, UnsupportedJwtException.class})
    public ResponseEntity<ExceptionResponse> handleInvalidJwt(Exception ex) {
        ExceptionEnum exceptionEnum = ExceptionEnum.INVALID_TOKEN;
        ExceptionResponse response = new ExceptionResponse(
                exceptionEnum.getCode(),
                exceptionEnum.getMsg()
        );
        return new ResponseEntity<>(response, HttpStatus.UNAUTHORIZED);
    }

    // 处理通用异常
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ExceptionResponse> handleGeneralException(Exception ex) {
        log.info("通用系统错误: {},{}",ex.getMessage(),ex.getStackTrace());
        ExceptionEnum exceptionEnum = ExceptionEnum.INTERNAL_SERVER_ERROR;
        ExceptionResponse response = new ExceptionResponse(
                exceptionEnum.getCode(),
                exceptionEnum.getMsg()
        );
        return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);
    }
    //服务异常
    @ExceptionHandler(RetryableException.class)
    public ResponseEntity<ExceptionResponse> handleGeneralException(RetryableException ex) {
        log.info("服务异常: {},{}",ex.getMessage(),ex.getStackTrace());
        ExceptionEnum exceptionEnum = ExceptionEnum.SERVICE_UNAVAILABLE;
        ExceptionResponse response = new ExceptionResponse(
                exceptionEnum.getCode(),
                exceptionEnum.getMsg()
        );
        return new ResponseEntity<>(response, HttpStatus.SERVICE_UNAVAILABLE);
    }
    // 根据业务状态码获取对应的HTTP状态
    private HttpStatus getHttpStatusByCode(int code) {
        if (code >= 200 && code < 300) {
            return HttpStatus.valueOf(code);
        } else if (code >= 400 && code < 500) {
            return HttpStatus.valueOf(code);
        } else if (code >= 500 && code < 600) {
            return HttpStatus.valueOf(code);
        } else if (code >= 1000 && code < 2000) { // 认证授权相关
            return HttpStatus.UNAUTHORIZED;
        } else if (code >= 2000 && code < 3000) { // 用户相关
            return HttpStatus.BAD_REQUEST;
        } else if (code >= 3000 && code < 4000) { // 数据资源相关
            return HttpStatus.BAD_REQUEST;
        } else if (code >= 4000 && code < 5000) { // 系统服务相关
            return HttpStatus.INTERNAL_SERVER_ERROR;
        } else {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
    }
}
